#include "calculator.hpp"
#include "tcpsever.hpp"

using namespace std;
using namespace user_protocol;

using call_back_t = function<user_protocol::Response(const user_protocol::Request &req)>;
void Usege(string argv)
{
    cout << argv << " + local_port" << endl;
}

class CalService
{
public:
    CalService(call_back_t cb)
        : _cb(cb)
    {
    }
    ~CalService()
    {
    }
    void Service(socket_sptr sockptr, InetAddr client)
    {
        int socket = sockptr->sockfd();

        LOG(DEBUG, "get a new link, info %s:%d, fd : %d\n", client.Ip().c_str(), client.Port(), socket);
        string str;
        while (1)
        {
            // 0.定义 req 接收一个请求
            user_protocol::Request req;

            int n = sockptr->Recv(&str); // 保证不了读到的是一个完整的请求
            if (n < 0)
            {
                LOG(ERROR, "不是一个完整的请求: [%s,%d]", client.Ip().c_str(), client.Port());
                break;
            }
            cout << "——————————————————————看看下面到底接收到了没" << endl;
            cout << "oper是:" << req._oper << "看不到！" << endl;
            string package;
            while (1)
            {
                sleep(1);
                // 1.收到请求后，去报头
                package = Decode(str);
                if (package.empty())
                    break;
                // 2.反序列化
                req.DeSerialization(package);
                // 3.得到看得懂的请求，做出回复（在这里就是让Response对象做计算）(业务处理)
                user_protocol::Response re = _cb(req);
                // 4.Response计算完成，要返回给Request看得懂的字节流
                // 序列化
                string send_str;
                re.Serialization(&send_str);
                cout << "——————————————————————————————————————————" << endl;
                cout << "send_str结果:" << send_str << endl;
                // 5.给回复添加长度报头
                send_str = Encode(send_str);

                //发出去
                sockptr->Send(send_str);
            }
        }
       
    }

private:
    call_back_t _cb;
};

int main(int args, char *argv[])
{
    EnableCout();
    if (args != 2)
    {
        Usege(argv[0]);
        exit(USEGE_ERROR);
    }
    uint16_t port = stoi(argv[1]);
    calculator cal;
    CalService cs(bind(&calculator::Excute, &cal, placeholders::_1)); // 服务里调业务

    io_service_t service = std::bind(&CalService::Service, &cs, std::placeholders::_1, std::placeholders::_2); // 调服务
    unique_ptr<Tcpsever> local = make_unique<Tcpsever>(port, service);
    // local->InitSever();
    local->Loop();
    return 0;
}
